home *** CD-ROM | disk | FTP | other *** search
/ MacWorld 1995 November / Macworld Nov ’95.toast / Developers / BoxMaker++ / BoxMaker++ ƒ / sources / preferences.cp < prev    next >
Encoding:
Text File  |  1995-06-14  |  2.7 KB  |  114 lines  |  [TEXT/KAHL]

  1. #include <Files.h>
  2. #include <Finder.h>
  3. #include <Folders.h>
  4.  
  5. #include "preferences.h"
  6.  
  7. template<class C> preferences<C>::preferences( Str255 fName, const C &defaults,
  8.     OSType fileCreator) : iFileCreator( fileCreator)
  9. {
  10.     //
  11.     // if the preferences file exists already, use the defaults specified in it
  12.     // instead of the defaults passed to us.
  13.     //
  14.     long foundDirID;
  15.     short foundVRefnum;
  16.  
  17.     short theFile;
  18.     long numtoread = sizeof( C);
  19.     
  20.     (void)FindFolder( kOnSystemDisk, 'pref', kCreateFolder, &foundVRefnum, &foundDirID);
  21.     (void)FSMakeFSSpec( foundVRefnum, foundDirID, fName, &theFileSpec);
  22.     
  23.     if( FSpOpenDF( &theFileSpec, fsCurPerm, &theFile) == noErr)
  24.     {
  25.         if( FSRead( theFile, &numtoread, (Ptr)&theDefaults) != noErr)
  26.         {
  27.             //
  28.             // Could not read entire preferences file, possibly because of a
  29.             // version change => use defaults
  30.             //            
  31.             theDefaults = defaults;
  32.         }
  33.         (void)FSClose( theFile);
  34.     } else {
  35.         theDefaults = defaults;
  36.     }
  37.     //
  38.     // Start with default values:
  39.     //
  40.     *(C*)this = theDefaults;
  41. }
  42.  
  43. template<class C> preferences<C>::~preferences()
  44. {
  45.     if( defaultsChanged())
  46.     {
  47.         long foundDirID;
  48.         short foundVRefnum;
  49.         //
  50.         // Create the preferences file, in case it doesn't exist yet
  51.         // This will fail if the file exists already, but we don't care
  52.         // about that.
  53.         //
  54.         short theFile;
  55.         FSpCreateResFile( &theFileSpec, iFileCreator, 'pref', 0);
  56.         if( ResError() == 0)
  57.         {
  58.             //
  59.             // First time through: put 'STR ' resource in,
  60.             // if it can be found in the application.
  61.             //
  62.             const short applResFile = CurResFile();
  63.             theFile = FSpOpenResFile( &theFileSpec, fsWrPerm);
  64.             if( theFile != -1)
  65.             {
  66.                 UseResFile( applResFile);
  67.                 Handle theRes = Get1Resource( 'STR ', kPreferencesInfo);
  68.                 if( theRes != 0)
  69.                 {
  70.                     DetachResource( theRes);
  71.                     UseResFile( theFile);
  72.                     AddResource( theRes, 'STR ', kPreferencesInfo, "\p");
  73.                     ReleaseResource( theRes);    // AddResource made it a resource again
  74.                 }
  75.                 CloseResFile( theFile);
  76.             }
  77.             //
  78.             // Set 'Name Locked' flag of preferences file:
  79.             //
  80.             FInfo theInfo;
  81.             if( FSpGetFInfo( &theFileSpec, &theInfo) == noErr)
  82.             {
  83.                 theInfo.fdFlags |= kNameLocked;
  84.                 (void)FSpSetFInfo( &theFileSpec, &theInfo);
  85.             }
  86.         }
  87.         if( FSpOpenDF( &theFileSpec, fsWrPerm, &theFile) == noErr)
  88.         {
  89.             long numtowrite = sizeof( C);
  90.             (void)FSWrite( theFile, &numtowrite, (Ptr)(C*)this);
  91.             FSClose( theFile);
  92.         }
  93.     }
  94. }
  95.  
  96. template<class C> Boolean preferences<C>::defaultsChanged() const
  97. {
  98.     const char *one   = (const char *)this;
  99.     const char *other = (const char *)&theDefaults;
  100.     const int numBytes = sizeof( C);
  101.     Boolean result = false;
  102.     
  103.     for( int i = 0; i < numBytes; i++)
  104.     {
  105.         if( *one++ != *other++)
  106.         {
  107.             result = true;
  108.             break;
  109.         }
  110.     }
  111.     return result;
  112. }
  113.  
  114.